package cn.heyige.backend.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.heyige.backend.entity.UserQuotaDO;
import cn.heyige.backend.mapper.UserQuotaMapper;
import cn.heyige.backend.service.UserQuotaService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;

/**
 * 用户配额服务实现类 - 精简版
 *
 * 专注于核心用户配额管理功能，提高系统性能和可维护性
 * 增强数据验证和错误处理
 *
 * @author CodeBuddy
 */
@Service("userQuotaService")
@Slf4j
@RequiredArgsConstructor
public class UserQuotaServiceImpl extends ServiceImpl<UserQuotaMapper, UserQuotaDO> implements UserQuotaService {
    
    @Override
    public boolean checkQuotaAvailable(Long userId, String quotaType, Integer requiredAmount) {
        // 参数校验
        if (userId == null) {
            log.warn("检查配额可用性失败：用户ID为空");
            return false;
        }

        if (!StringUtils.hasText(quotaType)) {
            log.warn("检查配额可用性失败：配额类型为空");
            return false;
        }

        if (requiredAmount == null || requiredAmount <= 0) {
            log.warn("检查配额可用性失败：所需配额数量无效");
            return false;
        }

        try {
            LambdaQueryWrapper<UserQuotaDO> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(UserQuotaDO::getUserId, userId.intValue());
            
            UserQuotaDO userQuota = getOne(queryWrapper);
            if (userQuota == null) {
                log.info("用户配额不存在：userId={}, quotaType={}", userId, quotaType);
                return false;
            }

            return userQuota.getRemainingQuota() >= requiredAmount;
        } catch (Exception e) {
            log.error("检查配额可用性失败：userId={}, quotaType={}, requiredAmount={}",
                    userId, quotaType, requiredAmount, e);
            return false;
        }
    }
    
    @Override
    @Transactional
    public boolean deductQuota(Long userId, String quotaType, Integer amount) {
        // 参数校验
        if (userId == null) {
            log.warn("扣除配额失败：用户ID为空");
            return false;
        }

        if (!StringUtils.hasText(quotaType)) {
            log.warn("扣除配额失败：配额类型为空");
            return false;
        }

        if (amount == null || amount <= 0) {
            log.warn("扣除配额失败：配额数量无效");
            return false;
        }

        try {
            LambdaQueryWrapper<UserQuotaDO> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(UserQuotaDO::getUserId, userId.intValue());
            
            UserQuotaDO userQuota = getOne(queryWrapper);
            if (userQuota == null) {
                log.info("用户配额不存在，无法扣除：userId={}, quotaType={}", userId, quotaType);
                return false;
            }

            if (userQuota.getRemainingQuota() < amount) {
                log.warn("用户配额不足，无法扣除：userId={}, quotaType={}, amount={}, remainingQuota={}",
                        userId, quotaType, amount, userQuota.getRemainingQuota());
                return false;
            }

            // 使用配额
            for (int i = 0; i < amount; i++) {
                userQuota.useOneQuota();
            }
            userQuota.setLastUsedTime(LocalDateTime.now());
            return updateById(userQuota);
        } catch (Exception e) {
            log.error("扣除配额失败：userId={}, quotaType={}, amount={}",
                    userId, quotaType, amount, e);
            return false;
        }
    }
    
    @Override
    @Transactional
    public boolean addQuota(Long userId, String quotaType, Integer amount) {
        // 参数校验
        if (userId == null) {
            log.warn("增加配额失败：用户ID为空");
            return false;
        }

        if (!StringUtils.hasText(quotaType)) {
            log.warn("增加配额失败：配额类型为空");
            return false;
        }

        if (amount == null || amount <= 0) {
            log.warn("增加配额失败：配额数量无效");
            return false;
        }

        try {
            LambdaQueryWrapper<UserQuotaDO> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(UserQuotaDO::getUserId, userId.intValue());
            
            UserQuotaDO userQuota = getOne(queryWrapper);
            if (userQuota == null) {
                // 如果配额不存在，则创建新的配额记录
                userQuota = new UserQuotaDO();
                userQuota.setUserId(userId.intValue());
                userQuota.setCreateTime(LocalDateTime.now());
                userQuota.setUpdateTime(LocalDateTime.now());
                
                // 根据配额类型增加不同的配额
                if ("FREE".equals(quotaType)) {
                    userQuota.addFreeQuota(amount);
                } else {
                    userQuota.addTotalQuota(amount);
                }
                return save(userQuota);
            } else {
                // 如果配额已存在，则增加配额数量
                if ("FREE".equals(quotaType)) {
                    userQuota.addFreeQuota(amount);
                } else {
                    userQuota.addTotalQuota(amount);
                }
                userQuota.setUpdateTime(LocalDateTime.now());
                return updateById(userQuota);
            }
        } catch (Exception e) {
            log.error("增加配额失败：userId={}, quotaType={}, amount={}",
                    userId, quotaType, amount, e);
            return false;
        }
    }
    
    @Override
    public Integer getQuotaAmount(Long userId, String quotaType) {
        // 参数校验
        if (userId == null) {
            log.warn("获取配额数量失败：用户ID为空");
            return 0;
        }

        if (!StringUtils.hasText(quotaType)) {
            log.warn("获取配额数量失败：配额类型为空");
            return 0;
        }

        try {
            LambdaQueryWrapper<UserQuotaDO> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(UserQuotaDO::getUserId, userId.intValue());
            
            UserQuotaDO userQuota = getOne(queryWrapper);
            if (userQuota == null) {
                log.info("用户配额不存在：userId={}, quotaType={}", userId, quotaType);
                return 0;
            }

            // 根据配额类型返回不同的配额数量
            if ("FREE".equals(quotaType)) {
                return userQuota.getFreeQuota();
            } else if ("TOTAL".equals(quotaType)) {
                return userQuota.getTotalQuota();
            } else if ("USED".equals(quotaType)) {
                return userQuota.getUsedQuota();
            } else {
                return userQuota.getRemainingQuota();
            }
        } catch (Exception e) {
            log.error("获取配额数量失败：userId={}, quotaType={}",
                    userId, quotaType, e);
            return 0;
        }
    }
}